<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>登录</title>
	<script src="//cdn.bootcss.com/socket.io/1.7.2/socket.io.js"></script>

	<link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css">
	<script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
	<script src="//cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.js"></script>
	<script src="https://code.ciphertrick.com/demo/jquerysession/js/jquerysession.js"></script>
	<!--输入框自动完成-->
	<script src="//cdn.bootcss.com/bootstrap-3-typeahead/4.0.2/bootstrap3-typeahead.min.js"></script>
	<!--spinner数字输入-->
	<script src="//cdn.bootcss.com/bootstrap-touchspin/3.1.2/jquery.bootstrap-touchspin.min.js"></script>
</head>
<style>
 body {
	padding-top: 50px;
	padding-left: 50px;
}
</style>
<body>
<div class="container">
	<br><br>
	<div class="input-group input-group-sm" about="登录">
		<span class="input-group-addon">帐号</span>
		<input id="investor" width="100" type="text" class="form-control" placeholder="输入帐号">
		<span class="input-group-addon">密码</span>
		<input id="pwd" width="100" type="password" class="form-control" placeholder="输入密码">
		<span class="input-group-btn">
			<button id="login"  class="btn btn-default" type="button">登录</button>
		</span>
	</div>
	<br>

	<div class="input-group input-group-sm" about="下单">
		<span class="input-group-addon" id="inst">合约</span>
		<input size="18" type="text" id="instrument" class="form-control" data-provide="typeahead">

		<span class="input-group-addon">手数</span>
		<input size=10 class="form-control" type="number" id="lots" value="1" min="1">

		<span class="input-group-addon">价格</span>
		<input class="form-control" type="number" id="price" value="9999" step="0.01">

		<span class="input-group-addon">
		<input type="radio" id="offset_open" name="offset" checked="checked">开仓
		<input type="radio" id="offset_close" name="offset">平仓
		</span>

		<span class="input-group-addon">偏移</span>
		<input class="form-control" type="number" id="diff" value="0" min="0">

		<span class="input-group-btn">
			<button type="button" class="btn btn-success" id="buy" onclick="order('buy')">买</button>
			<button type="button" class="btn btn-danger" id="sell" onclick="order('sell')">卖</button>
		</span>
	</div>
	<br>

	<table class="table table-bordered table-striped table-condensed table-hover" id="tick">
		<thead></thead>
		<tbody></tbody>
	</table>

	<div about="数据表格">
	<table class="table table-bordered table-striped table-condensed table-hover" id="account">
		<caption>权益</caption>
		<thead></thead>
		<tbody></tbody>
	</table>

	<table class="table table-bordered table-striped table-condensed table-hover" id="position">
		<caption>持仓</caption>
		<thead></thead>
		<tbody></tbody>
	</table>

	<table class="table table-bordered table-striped table-condensed table-hover" id="order">
		<caption>委托</caption>
		<thead></thead>
		<tbody></tbody>
	</table>

	<table class="table table-bordered table-striped table-condensed table-hover" id="trade">
		<caption>成交</caption>
		<thead></thead>
		<tbody></tbody>
	</table>
	</div>

	<footer>
		<pre id="rsp_info">no error ... </pre>
	</footer>
</div>
	<script>
		var table_cols = {};
		//去掉order,trade中的OrderID
		table_cols['order'] = new Array("InstrumentID", "Direction", "Offset", "LimitPrice", "AvgPrice", "InsertTime", "TradeTime", "TradeVolume", "Volume", "VolumeLeft", "Status", "StatusMsg", "IsLocal", "Custom", "SysID");
		table_cols['trade'] = new Array("TradeID", "InstrumentID", "ExchangeID", "Direction", "Offset", "Price", "Volume", "TradeTime", "TradingDay", "SysID");
		table_cols['position'] = new Array("InstrumentID", "Direction", "Price", "Position", "TdPosition", "YdPosition", "CloseProfit", "PositionProfit", "Commission", "Margin");
		table_cols['account'] = new Array("PreBalance", "PositionProfit", "CloseProfit", "Commission", "CurrMargin", "FrozenCash", "Available", "Fund", "Risk");
		table_cols['tick'] = new Array("Instrument", "LastPrice", "AskPrice", "AskVolume", "BidPrice", "BidVolume", "UpdateTime", "Volume", "OpenInterest", "AveragePrice");

		var ctp = null;
		var sid = '';
		var sub_inst = '';

		$(document).ready(function () {
			init_table('account');
			init_table('order');
			init_table('trade');
			init_table('position');
			init_table('tick');


			//如果登录成功后刷新，则再次登录
			var loginfo = $.session.get('login');
			if(loginfo != null){
				loginfo = eval('(' + loginfo + ')');
				$('#investor').val(loginfo['investor']);
				$('#pwd').val(loginfo['pwd']);
				login();
			}
		});

		function init_table(table_name) {
			var cols = table_cols[table_name];

			//用html()或$("#xx")[0].innerHTML
			$("#"+table_name + " thead").html('<tr></tr>');
			var title = $("#"+table_name + " thead tr")
			for(var v in cols){
				title.append('<th>'+cols[v]+'</th>');
			}
		}

		function table_show(table_name, data) {
			var cols = table_cols[table_name];
			var key = null;

			switch(table_name){
				case "order":
					key = data["OrderID"].replace(/\|/g, '');
					break;
				case "trade":
					key = $.trim(data["TradeID"]);
					break;
				case "position":
					key = data["InstrumentID"]+"_"+data["Direction"];
					break;
				case "account":
					key = data["Investor"];
					break;
				case "tick":
					key = data["Instrument"];
					break;
			}

			//if(table_name=="trade")//order的id xxx|xx|xx 由于有|会导致bug//trade.TradeID去掉前空格否则报错
			//	alert(key);
			var tr = $("#"+table_name + ' tbody').children("#"+key);
			if(tr.length == 0) {
				$("#"+table_name + ' tbody')[0].innerHTML += '<tr id="' + key + '"></tr>';
				tr = $("#"+table_name + " tbody #"+key);
				//添加数据行时设置格式
				for(var v in cols){
					var val = data[cols[v]];
					if(typeof(val) == "number")// !isNaN(val)) //数字
						val = val.toFixed(2);
					tr.append('<td id="'+cols[v]+'">' + val + '</td>');
					if(!isNaN(data[cols[v]])) //数字:右对齐
						tr.children("#"+cols[v]).css('text-align', 'right');
				}
			}
			else{
				tr = $("#"+table_name + " tbody #"+key);
				for(var v in cols){
					var val = data[cols[v]];
					if(typeof(val) == "number") //if(!isNaN(val)) //数字
						val = val.toFixed(2);
					tr.children("#"+cols[v]).first().text(val);
				}
			}
			//过滤持仓为0的数据
			if(table_name == 'position'){
				if(data['Position'] == 0){
					tr.hide();
				}
				else {
					tr.show();
				}
			}
		}

		function show_info(msg) {
			var rsp_info = document.getElementById("rsp_info");
			var now = new Date();
			//$("#rsp_info").html(now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds() + '\t' + JSON.stringify(msg));
			rsp_info.innerHTML += "<p>" + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds() + '\t' + JSON.stringify(msg) + "</p>";
		}

		function io_emit(event, dict) {
			if(ctp == null) return;
			dict['sid'] = sid;
			ctp.emit(event, dict);
		}

		function order(dire) {
			var inst = document.getElementById('instrument').value;
			var lots = document.getElementById('lots').value;
			var price = document.getElementById('price').value;
			var offset = document.getElementById('offset_open').checked?'open':'close';
			var diff = document.getElementById('diff').value;

			if(ctp == null) return;

			io_emit('order', {
				'instrument': inst,
				'lots': lots,
				'price': price,
				'direction': dire,
				'offset': offset
			});
		}

		$("#login").click(function () {
			login();
		});

		function login(){
			$.session.clear();

			ctp = io.connect('http://'+document.location.href.split('/')[2]+'/ctp', {'reconnect':true, 'auto connect':true,'force new connection':false, 'multiplex': false});

			ctp.on('connect',function () {
			});

			ctp.on('disconnect',function () {
				show_info('disconnected.');
			});

			ctp.on('sid',function (data) {
				sid = data;
				io_emit('login', {'investor': $('#investor').val(), 'pwd': $('#pwd').val()});
			});

			ctp.on('rsp_login', function (data) {
				show_info(data);
				if(data['ErrorID'] != 0){
					io_emit('release', {'investor': $('#investor').val()});
					io.socket.disconnect();
				}
				else{
					$.session.set('login', "{'investor': '"+$('#investor').val()+"', 'pwd': '"+$('#pwd').val()+"'}");
				}
			});

			//返回合约列表:可能出现多次返回的情况待处理******
			ctp.on('rsp_instrument', function (data) {
				var src = [];
				//如何判断是否处理过？$input.typeahead();
				for(var i = 0; i<data.length; i++) {
					src.push({name: data[i]['InstrumentID'], val: data[i]});
				}
				src.sort(function (a, b) {
					var x = a["name"];
					var y = b["name"];
					return x < y ? -1 : 1;
				});
				var $input = $('#instrument');
				$input.typeahead({source: src, autoSelect: true});
				$input.change(function(i, oldval) {
					var current = $input.typeahead("getActive");
					if (current) {
						// Some item from your model is active!
						if (current.name == $input.val()) {
							// This means the exact match is found. Use toLowerCase() if you want case insensitive match.
							var instField = current['val'];
							$('#price').attr('step', instField['PriceTick']);

							if(sub_inst != ''){
								$("#tick tbody #"+sub_inst).remove();
								//$('#tick tbody').remove($('#'+sub_inst));
								io_emit('unsub_inst',{'instrument': sub_inst});
							}
							sub_inst = current.name;
							io_emit('sub_inst',{'instrument': sub_inst});
						} else {
							// This means it is only a partial match, you can either add a new item
							// or take the active if you don't want new items
						}
					} else {
						// Nothing is active so it is a new value (or maybe empty value)
					}
				});

			});

			ctp.on('rtn_tick', function (data) {
				if(Math.abs($("#price").val() - data['LastPrice']) > 100){
					$("#price").val(data['LastPrice']);
				}
				table_show('tick', data);
			});

			ctp.on('rsp_account', function (data) {
				table_show('account', data);
			});

			ctp.on('rsp_position', function (data) {
				for(var i=0;i<data.length;i++) {
					table_show('position', data[i]);
				}
			});

			ctp.on('rtn_cancel', function (data) {
				table_show('order', data);
			});

			ctp.on('rtn_order', function (data) {
				table_show('order', data);
			});

			ctp.on('rtn_trade', function (data) {
				table_show('trade', data);
			});

			ctp.on('rtn_err_order', function (data) {
				table_show('order', data['order']);
				show_info(data['order']);
				show_info(data['info']);
			})
		}
	</script>
</body>
</html>